package com.inter.aspect;

import com.inter.my.YinXing;
import com.inter.util.RSAUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.UUID;

/**
 * @author yinxing
 * @date 2022-09-08
 */
@Aspect
@Slf4j
@Component
public class UserAspect {

    @Around("@annotation(yinXing)")
    public Object around(ProceedingJoinPoint point, YinXing yinXing) throws Throwable {

        //通过切入点获取目标class对象
        Class<?> aClass = point.getTarget().getClass();
        //获取接入点的类名
        String className = aClass.getName();
        //获取目标方法名称
        String methodName = point.getSignature().getName();
        //获取MyLog注解的value参数
        boolean encry = yinXing.encry();
        if (encry) {
            //拿到方法的入参
            Object[] args = point.getArgs();
            StringBuffer stringBuffer = new StringBuffer();
            log.info("\n===解密前===UserAspect," +
                    "类名[{}]," +
                    "方法名[{}]" +
                    "注解值:[{}]" +
                    "参数:[{}]", className, methodName, encry, args);
            for (int i = 0; i < args.length; i++) {
                Map<String, Object> argMap = (Map<String, Object>) args[i];
                for (Map.Entry<String, Object> entry : argMap.entrySet()) {
                    argMap.put(entry.getKey(), RSAUtils.decode(entry.getValue().toString()));
                }
                args[i] = argMap;
            }
            UUID uuid = UUID.randomUUID();
            log.info("\n===解密后===UserAspect-{}," +
                    "类名[{}]," +
                    "方法名[{}]" +
                    "注解值:[{}]" +
                    "参数:[{}]", uuid, className, methodName, encry, args);
            long startTime = System.currentTimeMillis();
            //运行目标方法
            Object proceed = point.proceed(args);
            long endTime = System.currentTimeMillis();
            log.info("\n===返回的参数加密前===UserAspect-{}," +
                    "类名[{}]," +
                    "方法名[{}]" +
                    "注解值:[{}]" +
                    "耗时:[{}ms]" +
                    "返回参数:[{}]", uuid, className, methodName, encry, endTime - startTime, proceed.toString());
            Map<String, Object> proceedMap = (Map<String, Object>) proceed;
            for (Map.Entry<String, Object> entry : proceedMap.entrySet()) {
                proceedMap.put(entry.getKey(), RSAUtils.encode(entry.getValue().toString()));
            }
            log.info("\n===返回的参数加密后===UserAspect-{}," +
                    "类名[{}]," +
                    "方法名[{}]" +
                    "注解值:[{}]" +
                    "耗时:[{}ms]" +
                    "返回参数:[{}]", uuid, className, methodName, encry, endTime - startTime, proceedMap);
            return proceedMap;
        } else {
            Object proceed = point.proceed();
            return proceed;
        }
    }
}
